package storage.beans;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import storage.statistics.Statistic;

public class SimulationBean implements Comparable {
  private String tilt;
  private String eccentricity;
  private String precision;
  private String samplingRate;
  private String temporalAccuracy;
  private String gridSpacing;
  private String timeStep;
  private String sStartDateTime;
  private String sEndDateTime;
  private long lStartDateTime;
  private long lEndDateTime;
  private String radius;
  private String timestamp;
  private Region region;
  private List gridSnapshots;
  private Iterator gridIterator;
  private Map statistics;
  private Iterator statIterator;
  
  public SimulationBean() {
    gridSnapshots = new ArrayList();
    statistics = new HashMap();
  }
  
  /**
   * Initializes an iterator over the set of GridBean objects contained in this bean.
   */
  public void initStatIterator() {
    statIterator = statistics.keySet().iterator();
  }
  
  /**
   * SimulationBean.initStatIterator() should be called before calling this for the first time.
   * @return null if there are no more Statistic objects to return
   */
  public Statistic getNextStatistic() {
    if(statIterator.hasNext())
      return (Statistic)statistics.get(statIterator.next());
    else
      return null;
  }
  
  /**
   * Initializes an iterator over the set of GridBean objects contained in this bean.
   */
  public void initGridIterator() {
    gridIterator = gridSnapshots.iterator();
  }
  
  public void addStatistic(Statistic stat) {
    statistics.put(stat.getType(), stat);
  }
  
  /**
   * SimulationBean.initGridIterator() should be called before calling this for the first time.
   * @return null if there are no more GridBean objects to return
   */
  public GridBean getNextGrid() {
    if(gridIterator.hasNext())
      return (GridBean)gridIterator.next();
    else
      return null;
  }

  public void addSnapshot(GridBean grid) {
    gridSnapshots.add(grid);
  }
  
  public void setPrecision(int precision) {
    try {
      this.precision = String.valueOf(precision);
    }
    catch (NumberFormatException e) {
      this.precision = String.valueOf(-1);
    }
  }
  
  public void setSamplingRate(int samplingRate) {
    this.samplingRate = String.valueOf(samplingRate);
  }
  
  public void setTemporalAccuracy(int temporalAccuracy) {
    this.temporalAccuracy = String.valueOf(temporalAccuracy);
  }
  
  public String getRadius() {
    return radius;
  }
  
  public void setRadius(int radius) {
    this.radius = String.valueOf(radius);
  }

  public String getEccentricity() {
    return eccentricity;
  }

  public void setEccentricity(float eccentricity) {
    this.eccentricity = String.valueOf(eccentricity);
  }

  public String getEndDateTimeString() {
    return sEndDateTime;
  }
  
  public long getEndDateTime() {
    return lEndDateTime;
  }

  public void setEndDateTime(long endDateTime) {
    this.sEndDateTime = String.valueOf(endDateTime);
    this.lEndDateTime = endDateTime;
  }

  public String getGridSpacing() {
    return gridSpacing;
  }

  public void setGridSpacing(int gridSpacing) {
    this.gridSpacing = String.valueOf(gridSpacing);
  }

  public String getPrecision() {
    return precision;
  }

  public String getSamplingRate() {
    return samplingRate;
  }

  public String getStartDateTimeString() {
    return sStartDateTime;
  }
  
  public long getStartDateTime() {
    return lStartDateTime;
  }

  public void setStartDateTime(long startDateTime) {
    this.sStartDateTime = String.valueOf(startDateTime);
    this.lStartDateTime = startDateTime;
  }

  public String getTemporalAccuracy() {
    return temporalAccuracy;
  }

  public String getTilt() {
    return tilt;
  }

  public void setTilt(int tilt) {
    this.tilt = String.valueOf(tilt);
  }

  public String getTimeStep() {
    return timeStep;
  }

  public void setTimeStep(int timeStep) {
    this.timeStep = String.valueOf(timeStep);
  }
  
  public void setTimestamp(long timestamp) {
    this.timestamp = String.valueOf(timestamp);
  }
  
  public String getTimestamp() {
    return timestamp;
  }

  public Region getRegion() {
    return region;
  }

  public void setRegion(Region region) {
    this.region = region;
  }
  
  /**
   * This is not a comparison of equality - it is used for ranking one bean against 
   * another based on criteria outlined in the Query class.
   */
  public int compareTo(Object obj) {
    //start off assuming this object is ranked higher than the other
    int retVal = 1;
    
    SimulationBean bean = (SimulationBean)obj;
    if(this.region.getArea() < bean.getRegion().getArea())
      retVal = -1;
    else if(this.region.getArea() == bean.getRegion().getArea()) {      
      //compare the date range
      long thisDateRange = lEndDateTime - lStartDateTime;
      long thatDateRange = bean.getEndDateTime() - bean.getStartDateTime();
      
      if(thisDateRange < thatDateRange)
        retVal = -1;
      else if(thisDateRange == thatDateRange) {
        //compare the timestamps
        long thisTimestamp = Long.parseLong(timestamp);
        long thatTimestamp = Long.parseLong(bean.getTimestamp());
        if(thisTimestamp < thatTimestamp)
          retVal = -1;        
      }
    }
    
    return retVal;
  }
}
